package models

import (
	"database/sql"
	"fmt"
	"strconv"
)

type Post struct {
	BaseModel
	Title       string // title
	Body        string // body
	View        int    // view count
	IsPublished bool   // published or not
	Tags        []*Tag `gorm:"-"` // tags of post
	Comments    []*Comment `gorm:"-"` // comments of post
	CommentTotal int `gorm:"-"` // count of comment
}



// func==============
func ListTagByPostId(id string) ([]*Tag, error)  {
	var tags []*Tag
	pid ,err := StoUint(id)
	if err != nil {
		return nil, err
	}
	//rows, err := DB.Where("post_id=?", uint(pid)).Find(&tags).Rows()
	rows, err := DB.Raw("select t.* from tags t inner join post_tags pt on t.id=pt.tag_id where pt.post_id=?",
		uint(pid)).Rows()
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	for rows.Next() {
		var tag Tag
		DB.ScanRows(rows, &tag)
		//fmt.Println(tag)
		tags = append(tags, &tag)
	}
	return  tags, nil

}


func ListAllPost(tag string) ([]*Post, error) {
	return _listPost(tag, false, 0, 0)
}

func _listPost(tag string, published bool, pageIndex, pageSize int) ([]*Post, error) {
	var posts []*Post
	var err error

	if len(tag) > 0 {
		fmt.Println("tagId="+tag)
		tagId, err := strconv.ParseUint(tag, 10, 64)
		var rows *sql.Rows

		qry := DB.Table("posts").Joins("inner join post_tags pt on pt.post_id= posts.id").Where(
			"pt.tag_id=?", tagId)
		if published {
			qry = qry.Where("posts.is_published=?", true)
		}
		if pageIndex >0 {
			qry = qry.Limit(pageSize).Offset((pageIndex-1)*pageSize)
		}

		rows, err = qry.Order("created_at desc").Rows()

		if err != nil {
			fmt.Println(err)
			return nil, err
		}
		defer rows.Close()
		for rows.Next() {
			var post Post
			DB.ScanRows(rows, &post)
			posts = append(posts, &post)
		}
	} else {
		fmt.Println(pageIndex)
		fmt.Println(pageSize)
		qry := DB.Select("*")
		if published {
			qry = DB.Where("is_published=?", true)
		}
		if pageIndex >0 {
			qry = qry.Limit(pageSize).Offset((pageIndex - 1) * pageSize)
		}
		err = qry.Order("created_at desc").Find(&posts).Error
	}


	return posts, err
}

// Post
func (post *Post) Insert() error {
	return DB.Create(post).Error
}

func (post *Post) Update() error {
	return DB.Model(post).Updates(map[string]interface{}{
		"title": post.Title,
		"body": post.Body,
		"is_published": post.IsPublished,
	}).Error
}

func (post *Post) Delete() error {
	return DB.Delete(post).Error
}
